package cn.zlg.www.main;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager.widget.ViewPager;

import com.sany.canwifi.Jni;
import com.sany.canwifi.R;
import com.sany.canwifi.tcp.TcpClient;
import com.sany.canwifi.udp.MulticastListener;
import com.sany.canwifi.util.NetWorkUtils;

import java.util.ArrayList;

import cn.zlg.www.ControlCAN;
import cn.zlg.www.ErrData;
import cn.zlg.www.fragment.DisplayFragment;
import cn.zlg.www.fragment.SendFragment;
import cn.zlg.www.fragment.SetFragment;

public class MainActivity extends FragmentActivity {
    public static final String TAG = "MainActivity";
    private ViewPager mPager;
    private ArrayList<Fragment> mFragmentsList;
    private DisplayFragment mDisplayFragment = null;
    private SendFragment mSendFragment = null;
    private SetFragment mSetFragment = null;
    private TextView mDisplayTextView, mSendTextView, mSetTextView, mTitleTextView;
    private ImageView mDisplayImageView, mSendImageView, mSetImageView;
    private PopupWindow mPopupWindow;
    private MoreMenuClickListener mMoreItemClickListener;

    private MsgHandler msgHandler;

    public static final int TAB_DISPLAY = 0;
    public static final int TAB_SEND = 1;
    public static final int TAB_SET = 2;
    private static int mCurTabIndex = TAB_DISPLAY;

    private static final int MENU_WITH = 150;

    public static final int TYPE_TCP_SERVER = 0;
    public static final int TYPE_TCP_CLIENT = 1;
    public static final int TYPE_UDP = 2;
    public static final int TYPE_UNCONNECT = 3;
    public static final int TYPE_CLEAR = 4;
    public static final int TYPE_SEND_FRM = 5;
    public static final int TYPE_DISPLAY_LIST = 6;
    public static final int TYPE_EXIT_APP = 7;
    public static final int TYPE_OPEN_FILE_SAVED = 8;

    private ImageView mPauseImageView;
    private ImageView mClearImageView;
    private ImageView mMoreImageView;
    private ControlCAN controlCAN;
    private boolean mPaused = true;
    private Thread mFrmRecvThread, mErrRecvThread;
    private boolean mConnected;
    private float mDensity;
    private long mExitTimeCount;
    private long mClickTimeCount;

    static {
        System.loadLibrary("CANWifi");
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        controlCAN = new ControlCAN();
        initView();
        mDensity = getResources().getDisplayMetrics().density;
        msgHandler = new MsgHandler();
        Log.e(TAG, "onCreate: " + getApplicationInfo().nativeLibraryDir);
        Log.e(TAG, "onCreate: " + Jni.stringFromJNI());
        String ip = NetWorkUtils.getLocalIpAddress(this);
        //92.168.0.10
        Log.e(TAG, "onCreate: ip==" + ip);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        showMenu();
        return false;
    }

    private void initView() {
        LinearLayout dispLayout = (LinearLayout) findViewById(R.id.displaylinearLayout);
        dispLayout.setOnClickListener(new MyOnClickListener(TAB_DISPLAY));
        LinearLayout sendLayout = (LinearLayout) findViewById(R.id.sendlinearLayout);
        sendLayout.setOnClickListener(new MyOnClickListener(TAB_SEND));
        LinearLayout setLayout = (LinearLayout) findViewById(R.id.setlinearLayout);
        setLayout.setOnClickListener(new MyOnClickListener(TAB_SET));
        mDisplayTextView = (TextView) findViewById(R.id.displayTextview);
        mSendTextView = (TextView) findViewById(R.id.sendTextview);
        mSetTextView = (TextView) findViewById(R.id.setTextview);
        mSetTextView.setTextColor(getResources().getColor(
                R.color.cornflowerblue));
        mTitleTextView = (TextView) findViewById(R.id.textViewTitle);
        mDisplayImageView = (ImageView) findViewById(R.id.displayimageView);
        mDisplayImageView.setSelected(true);
        mSendImageView = (ImageView) findViewById(R.id.sendimageView);
        mSetImageView = (ImageView) findViewById(R.id.setimageView);

        mPauseImageView = (ImageView) findViewById(R.id.imageViewzPause);
        mPauseImageView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                if (System.currentTimeMillis() - mClickTimeCount < 1000) {
                    return;
                }
                if (mConnected) {
                    mPaused = !mPaused;
                    mSendFragment.setSendStatus(mPaused);
                    if (!mPaused) {
                        startRecvData();
                    }

                    mPauseImageView
                            .setImageResource(mPaused ? android.R.drawable.ic_media_play
                                    : android.R.drawable.ic_media_pause);
                } else {
                    Toast toast = Toast.makeText(MainActivity.this, "未连接",
                            Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                }
                mClickTimeCount = System.currentTimeMillis();
            }
        });
        mClearImageView = (ImageView) findViewById(R.id.imageViewdelete);
        mClearImageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                if (mDisplayFragment != null) {
                    AlertDialog clearDlg = new AlertDialog.Builder(
                            MainActivity.this)
                            .setIcon(android.R.drawable.ic_delete)
                            .setMessage("清空列表内容?")
                            .setPositiveButton("清空",
                                    new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(
                                                DialogInterface arg0, int arg1) {
                                            // TODO Auto-generated method stub
                                            mDisplayFragment.dealItem(
                                                    DisplayFragment.MSG_CLEAR,
                                                    null);
                                        }
                                    })
                            .setNegativeButton("取消",
                                    new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(
                                                DialogInterface arg0, int arg1) {
                                            // TODO Auto-generated method stub
                                        }
                                    }).create();
                    clearDlg.show();
                }
            }
        });
        mMoreImageView = (ImageView) findViewById(R.id.imageViewMore);
        mMoreImageView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                showMenu();
            }
        });
        mMoreItemClickListener = new MoreMenuClickListener();

        mPager = (ViewPager) findViewById(R.id.vPager);
        mFragmentsList = new ArrayList<Fragment>();

        mDisplayFragment = new DisplayFragment();
        mFragmentsList.add(mDisplayFragment);
        mSendFragment = new SendFragment();
        mFragmentsList.add(mSendFragment);
        mSetFragment = new SetFragment();
        mFragmentsList.add(mSetFragment);

        mPager.setAdapter(new MyFragmentPagerAdapter(
                getSupportFragmentManager(), mFragmentsList));
        mPager.setOnPageChangeListener(new MyOnPageSelectListener());
        mPager.setCurrentItem(TAB_SET);
    }

    private void multicastListener() {

//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                int port = 5000;
//                String host = "192.168.0.178";
//                MulticastListener ml = new MulticastListener(host, port);
//                ml.listen();
//            }
//        }).start();

    }

    private void initSendUdp() {
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    Send.send(MainActivity.this);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//        }).start();
        /* 接收tcp 连接*/
//        new tcpReceive(handler_for_udpReceiveAndtcpSend).start();

        autoConnectedWifi();
    }

    /**
     * socket connect
     */
    private void connect(String ip, int port) {
        Log.e(TAG, "connect: ip==" + ip + "，port==" + port);
        TcpClient.getInstance().connect(ip, port);
        TcpClient.getInstance().setOnDataReceiveListener(new TcpClient.OnDataReceiveListener() {
            @Override
            public void onConnectSuccess() {
                Log.e(TAG, "onConnectSuccess: ");
            }

            @Override
            public void onConnectFail(String error) {

                Log.e(TAG, "onConnectFail: " + error);
            }

            @Override
            public void onDataReceive(byte[] buffer, int size, int requestCode) {
                //获取有效长度的数据
                if (buffer == null) {
                    Log.e(TAG, "onDataReceive: null" );
                    return;
                }
                byte[] all = new byte[size];
                System.arraycopy(buffer, 0, all, 0, size);
                Log.d(TAG, "onDataReceive: string==" + new String(all));

            }
        });
    }

    /**
     * 自动连接cpe在使用wifi连接的情况下
     */
    private void autoConnectedWifi() {
        Log.e(TAG, "autoConnectedWifi: ");
        String ip = "192.168.0.178";
        String port = "4002";
        connect(ip, Integer.parseInt(port));
    }

    Handler handler_for_udpReceiveAndtcpSend = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            Log.e(TAG, "handleMessage: " + msg);

        }
    };

    private void exitApp() {
        mSetFragment.saveSetInfo();
        clearThread();
        finish();
    }

    private void showMenu() {
        if (mPopupWindow != null && mPopupWindow.isShowing()) {
            mPopupWindow.dismiss();
            mPopupWindow = null;
        } else {
            initMorePopupWindow();
            int nX = (int) ((25 - MENU_WITH) * mDensity);
            mPopupWindow.showAsDropDown(mMoreImageView, nX, 0);
        }
    }

    public void doCommand(int nType, Object obj) throws InterruptedException {
        switch (nType) {
            case TYPE_TCP_SERVER: {
                SetInfo setInfo = (SetInfo) obj;
                if (!controlCAN.initTCPServer(setInfo.nLocalPort, setInfo.ipAddress, setInfo.nPortErrNotice)) {
                    Toast toast = Toast.makeText(this, "初始化服务器失败", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    mSetFragment.setSureButtonFlag(false);
                    mPaused = true;
                    return;
                }
                connect();
                break;
            }
            case TYPE_TCP_CLIENT: {
                SetInfo setInfo = (SetInfo) obj;
                if (!controlCAN.initTCPClient(setInfo.ipAddress, setInfo.nWorkPort,
                        setInfo.nPortErrNotice)) {
                    Toast toast = Toast.makeText(this, "初始化客户端失败",
                            Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    mSetFragment.setSureButtonFlag(false);
                    mPaused = true;
                    return;
                }
                connect();
                break;
            }
            case TYPE_UDP: {
                SetInfo setInfo = (SetInfo) obj;
                mConnected = true;
                if (!controlCAN.initUDP(setInfo.nLocalPort, setInfo.ipAddress,
                        setInfo.nWorkPort, setInfo.nPortErrNotice)) {
                    Toast toast = Toast.makeText(this, "初始化服务器失败",
                            Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    mSetFragment.setSureButtonFlag(false);
                    mPaused = true;
                    return;
                }
                connect();
                break;
            }
            case TYPE_UNCONNECT: {
                if (controlCAN.close()) {
                    unConnect();
                    Toast toast = Toast
                            .makeText(this, "断开连接成功", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                } else {
                    mSetFragment.setSureButtonFlag(true);
                    Toast toast = Toast
                            .makeText(this, "断开连接失败", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                }
                break;
            }
            case TYPE_CLEAR: {
                mDisplayFragment.dealItem(DisplayFragment.MSG_CLEAR, null);
                break;
            }
            case TYPE_SEND_FRM: {
                if (mPaused || !mConnected) {
                    return;
                }
                ItemData itemData = (ItemData) obj;
                mDisplayFragment.dealItem(DisplayFragment.MSG_SEND, itemData);
                ItemData[] itemDatas = new ItemData[1];
                itemDatas[0] = itemData;
                if (!controlCAN.isConnected()) {
                    Message message = new Message();
                    message.what = TYPE_UNCONNECT;
                    msgHandler.sendMessage(message);
                    return;
                }
                boolean sendStatus = controlCAN.send(itemDatas, 1);
                Log.e(TAG, "doCommand: sendStatus==" + sendStatus);
                Log.e(TAG, "doCommand: itemDatas=="+itemData.toString() );
                break;
            }
            case TYPE_DISPLAY_LIST:
                mDisplayFragment.refreshRecvList();
                break;
            case TYPE_EXIT_APP:
                exitApp();
                break;
            case TYPE_OPEN_FILE_SAVED: {
                Message message = new Message();
                message.what = TYPE_OPEN_FILE_SAVED;
                message.obj = obj;
                msgHandler.sendMessage(message);
                break;
            }
            default:
                break;
        }
    }

    private void connect() {
        Log.e(TAG, "connect: ");
        mConnected = true;
        mPaused = false;
        mPauseImageView.setImageResource(android.R.drawable.ic_media_pause);
        mSetFragment.setSureButtonFlag(mConnected);
        mSendFragment.setSendStatus(mPaused);
        Toast toast = Toast.makeText(this, "连接成功", Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
        setTitle(mConnected);
        startRecvData();

//        startUdp();
//        initSendUdp();
//        multicastListener();
    }

    private void startUdp() {
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                new ReveiverUdp().start();
//            }
//        }).start();
    }

    private void unConnect() {
        mPaused = true;
        mPauseImageView.setImageResource(android.R.drawable.ic_media_play);
        mSetFragment.setSureButtonFlag(false);
        mSendFragment.setSendStatus(true);
        mConnected = false;
        setTitle(mConnected);
    }

    private void setTitle(boolean bConnected) {
        mTitleTextView.setText(bConnected ? "CANWifi[已连接]" : "CANWifi[未连接]");
    }

    public class MyOnClickListener implements OnClickListener {
        private int index = 0;

        public MyOnClickListener(int i) {
            index = i;
        }

        @Override
        public void onClick(View v) {
            if (setCurTabIndex(index)) {
                mPager.setCurrentItem(index);
            }
        }
    }

    ;

    public class MyOnPageSelectListener implements ViewPager.OnPageChangeListener {

        @Override
        public void onPageScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onPageSelected(int arg0) {
            // TODO Auto-generated method stub
            switch (arg0) {
                case TAB_DISPLAY:
                    setCurTabIndex(TAB_DISPLAY);
                    mDisplayFragment.refreshRecvList();
                    setDisplayToolBarStatus(true);
                    mDisplayImageView.setSelected(true);
                    mSendImageView.setSelected(false);
                    mSetImageView.setSelected(false);
                    mDisplayTextView.setTextColor(getResources().getColor(
                            R.color.cornflowerblue));
                    mSendTextView.setTextColor(getResources()
                            .getColor(R.color.gray));
                    mSetTextView
                            .setTextColor(getResources().getColor(R.color.gray));
                    break;
                case TAB_SEND:
                    setCurTabIndex(TAB_SEND);
                    setDisplayToolBarStatus(false);
                    mDisplayImageView.setSelected(false);
                    mSendImageView.setSelected(true);
                    mSetImageView.setSelected(false);
                    mDisplayTextView.setTextColor(getResources().getColor(
                            R.color.gray));
                    mSendTextView.setTextColor(getResources().getColor(
                            R.color.cornflowerblue));
                    mSetTextView
                            .setTextColor(getResources().getColor(R.color.gray));
                    break;
                case TAB_SET:
                    setCurTabIndex(TAB_SET);
                    setDisplayToolBarStatus(false);
                    mDisplayImageView.setSelected(false);
                    mSendImageView.setSelected(false);
                    mSetImageView.setSelected(true);
                    mDisplayTextView.setTextColor(getResources().getColor(
                            R.color.gray));
                    mSendTextView.setTextColor(getResources()
                            .getColor(R.color.gray));
                    mSetTextView.setTextColor(getResources().getColor(
                            R.color.cornflowerblue));
                    break;
                default:
                    break;
            }
        }

    }

    private void setDisplayToolBarStatus(boolean bVisiable) {
        if (bVisiable) {
            mClearImageView.setVisibility(View.VISIBLE);
            // mPauseImageView.setVisibility(View.VISIBLE);
        } else {
            mClearImageView.setVisibility(View.GONE);
            // mPauseImageView.setVisibility(View.GONE);
        }
    }

    private class FrmRecvRunnable implements Runnable {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            int nCount = 0;
            while (!mPaused) {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                boolean isConnec = controlCAN.isConnected();
//                Log.e(TAG, "FrmRecvRunnable run: isConnec==" + isConnec);
                if (mConnected && mDisplayFragment != null) {
                    if (!controlCAN.isConnected()) {
                        Message message = new Message();
                        message.what = TYPE_UNCONNECT;
                        msgHandler.sendMessage(message);
                        return;
                    }
                    if ((nCount = controlCAN.getReceiveNum()) <= 0) {
                        continue;
                    }
                    ItemData[] objs = new ItemData[nCount];
                    for (int i = 0; i < nCount; i++) {
                        objs[i] = new ItemData();
                    }
                    if (controlCAN.recv(objs, nCount) != nCount) {
                        continue;
                    }
                    Log.e(TAG, "FrmRecvRunnable run: recv==" + objs.toString());
                    for (int i = 0; i < nCount; i++) {
                        mDisplayFragment.dealItem(DisplayFragment.MSG_RECV, objs[i]);
                    }
                }

            }
        }
    }

    private class ErrInfoRunnable implements Runnable {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            ErrData errData = new ErrData();
            while (!mPaused) {
                if (mConnected && mDisplayFragment != null) {
                    if (controlCAN.readErrInfo(errData)) {
                        mDisplayFragment.dealItem(DisplayFragment.ERR_DATA, new ErrData(errData));
//                        Log.e(TAG, "ErrInfoRunnable run: " + errData.toString());
                    } else {
                        try {
//                            Log.e(TAG, "ErrInfoRunnable run: " + errData.toString());
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

    }

    public int getCurTabIndex() {
        return mCurTabIndex;
    }

    boolean setCurTabIndex(int nIndex) {
        if (mCurTabIndex == nIndex)
            return false;
        mCurTabIndex = nIndex;
        if (mCurTabIndex != TAB_DISPLAY) {
            mDisplayFragment.setListAdapterEmpty();
        } else {
            mDisplayFragment.setListAdapter();
        }
        return true;
    }

    public void clearThread() {
        mPaused = true;
        if (controlCAN != null && mConnected) {
            mConnected = false;
            controlCAN.close();
        }
    }

    private void initMorePopupWindow() {
        View moreView = getLayoutInflater().inflate(R.layout.more_menu, null);
        int nWidth = (int) (mDensity * MENU_WITH);
        mPopupWindow = new PopupWindow(moreView, nWidth,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        mPopupWindow.setBackgroundDrawable(getResources().getDrawable(
                R.drawable.plus));

        LinearLayout closeLayout = (LinearLayout) moreView
                .findViewById(R.id.moremenucloselayout);
        closeLayout.setOnClickListener(mMoreItemClickListener);
        LinearLayout aboutLayout = (LinearLayout) moreView
                .findViewById(R.id.moremenuaboutlayout);
        aboutLayout.setOnClickListener(mMoreItemClickListener);

        mPopupWindow.setFocusable(true);
        mPopupWindow.setOutsideTouchable(true);
        mPopupWindow.update();
    }

    private void startRecvData() {
        Log.e(TAG, "startRecvData: ");
        if (!mConnected) {
            return;
        }
        mPaused = false;
        mFrmRecvThread = new Thread(new FrmRecvRunnable());
        mFrmRecvThread.start();
        mErrRecvThread = new Thread(new ErrInfoRunnable());
        mErrRecvThread.start();
    }

    @Override
    protected void finalize() throws Throwable {
        // TODO Auto-generated method stub
        if (mSetFragment != null) {
            mSetFragment.saveSetInfo();
        }
        clearThread();
        super.finalize();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // TODO Auto-generated method stub
        if (KeyEvent.KEYCODE_BACK == keyCode) {
            if ((System.currentTimeMillis() - mExitTimeCount) > 2000) {
                Toast toast = Toast.makeText(this, "再按一次退出应用", Toast.LENGTH_SHORT);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();
                mExitTimeCount = System.currentTimeMillis();
            } else {
                exitApp();
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    private class MoreMenuClickListener implements OnClickListener {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mPopupWindow.dismiss();
            mPopupWindow = null;
            switch (v.getId()) {
                case R.id.moremenuaboutlayout:
                    View view = getLayoutInflater().inflate(R.layout.about, null);
                    new AlertDialog.Builder(MainActivity.this).setView(view).show();
                    break;
                case R.id.moremenucloselayout:
                    exitApp();
                    break;
                default:
                    break;
            }
        }
    }

    private class MsgHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            switch (msg.what) {
                case TYPE_UNCONNECT:
                    unConnect();
                    break;
            }
        }
    }
}
